using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

using Horizon;

namespace HorizonTestClient
{
    public partial class OptionsForm : Form
    {
        private bool exitingValue = false;
        private List<Library> librariesValue = new List<Library>();
        private Library selectedLibrary;
        private Patron selectedPatron;

        private UserInfoForm userForm = new UserInfoForm();
        private LibraryForm libForm = new LibraryForm();

        public OptionsForm()
        {
            InitializeComponent();

            unifiedHoldingsDataGridView.AutoGenerateColumns = false;

            librariesListBox.DisplayMember = "Name";
            patronsListBox.DisplayMember = "Name";

            AddHoldingsColumn("Due Date", "DueDate");
            AddHoldingsColumn("Title", "Title");
            AddHoldingsColumn("Patron", "Patron");
        }

        /// <summary>
        /// Set to indicate that application is exiting
        /// </summary>
        public bool Exiting
        {
            get { return exitingValue; }
            set { exitingValue = value; }
        }

        /// <summary>
        /// The collection of configured libraries 
        /// </summary>
        public List<Library> Libraries
        {
            get { return librariesValue; }
            set
            {
                librariesValue = value;
            }
        }

        /// <summary>
        /// Utility method to add a new data column to the DataGridView
        /// </summary>
        /// <param name="name">Name of new column</param>
        /// <param name="dataProperty">Databound property for this column</param>
        private void AddHoldingsColumn(string name, string dataProperty)
        {
            DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn();
            c.Name = name;
            c.HeaderText = name;
            c.DataPropertyName = dataProperty;
            c.SortMode = DataGridViewColumnSortMode.Automatic;

            unifiedHoldingsDataGridView.Columns.Add(c);
        }

        /// <summary>
        /// Updates the list of users when selected library changes
        /// </summary>
        private void librariesListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            selectedLibrary = (Library)(librariesListBox.SelectedItem);

            UpdateLibraryPatrons();
        }

        /// <summary>
        /// Removes selected patron, if one is selected
        /// </summary>
        private void removePatronButton_Click(object sender, EventArgs e)
        {
            if (patronsListBox.SelectedItem == null) return;
            else
            {
                selectedLibrary.Users.Remove((Patron)(patronsListBox.SelectedItem));

                UpdateLibraryPatrons();
            }
        }

        /// <summary>
        /// Sets up and shows LibraryForm dialog
        /// </summary>
        private void updateLibraryButton_Click(object sender, EventArgs e)
        {
            if (selectedLibrary != null)
            {
                libForm.CurrentLibrary = selectedLibrary;
                librariesListBox.DataSource = null;

                if (libForm.ShowDialog() == DialogResult.OK)
                {
                    librariesListBox.DataSource = librariesValue;
                    librariesListBox.DisplayMember = "Name";
                }
            }
        }

        /// <summary>
        /// Sets up and shows patron dialog to add new patron
        /// </summary>
        private void addPatronButton_Click(object sender, EventArgs e)
        {
            if (selectedLibrary == null) return;

            Patron newUser = new Patron();
            newUser.CurrentSession.SessionLibrary = selectedLibrary;
            userForm.SelectedPatron = newUser;

            if (userForm.ShowDialog() == DialogResult.OK)
            {
                selectedPatron = userForm.SelectedPatron;
                selectedLibrary.Users.Add(selectedPatron);

                UpdateLibraryPatrons();
            }
        }

        /// <summary>
        /// Updates list of users for this library and merges holdings for grid
        /// </summary>
        private void UpdateLibraryPatrons()
        {
            Patron tempSelectedPatron = selectedPatron;

            patronsListBox.DataSource = null;

            if (selectedLibrary != null)
            {
                patronsListBox.DataSource = selectedLibrary.Users;
                patronsListBox.DisplayMember = "Name";
                patronsListBox.SelectedItem = tempSelectedPatron;
            }

            UnifyHoldings();
        }

        /// <summary>
        /// Merges list of holdings for all patrons of one library
        /// </summary>
        private void UnifyHoldings()
        {
            unifiedHoldingsDataGridView.DataSource = null;

            if (selectedLibrary != null)
            {
                List<Holding> unifiedHoldings = new List<Holding>();
                foreach (Patron currUser in selectedLibrary.Users)
                {
                    unifiedHoldings.AddRange(currUser.ItemsOut);
                }
 
                unifiedHoldingsDataGridView.DataSource = unifiedHoldings;
            }
        }

        /// <summary>
        /// Called when Edit button is clicked for patron
        /// </summary>
        private void editPatronButton_Click(object sender, EventArgs e)
        {
            EditPatron();
        }

        /// <summary>
        /// Sets up and displays UserForm dialog, then updates unified holdings list
        /// </summary>
        private void EditPatron()
        {
            if (selectedPatron == null) return;

            userForm.SelectedPatron = selectedPatron;
            userForm.ShowDialog();

            UnifyHoldings();
        }

        /// <summary>
        /// Updates selected patron based on listbox change
        /// </summary>
        private void patronsListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            selectedPatron = (Patron)(patronsListBox.SelectedItem);
        }

        /// <summary>
        /// Updates combo boxes when form is shown
        /// </summary>
        private void OptionsForm_Shown(object sender, EventArgs e)
        {
            librariesListBox.DataSource = librariesValue;

            // Auto-select the first one
            if (librariesListBox.Items.Count > 0)
            {
                librariesListBox.SelectedIndex = 0;
            }
        }

        /// <summary>
        /// Renews selected holding from context menu
        /// </summary>
        private void renewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if( unifiedHoldingsDataGridView.SelectedRows.Count > 0 )
            {
                Holding h = (Holding)(unifiedHoldingsDataGridView.Rows[0].DataBoundItem);
                unifiedHoldingsDataGridView.DataSource = null;
                // Renew by library associated with the patron associated with this book
                h.Patron.CurrentSession.SessionLibrary.RenewHolding(selectedPatron, h);
                unifiedHoldingsDataGridView.DataSource = selectedPatron.ItemsOut;
            }
        }

        /// <summary>
        /// Formats overdue holding cells as red background
        /// </summary>
        private void unifiedHoldingsDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            Holding h = (Holding)(unifiedHoldingsDataGridView.Rows[e.RowIndex].DataBoundItem);
            TimeSpan ts = DateTime.Parse(h.DueDate).Subtract(DateTime.Now.Date);

            if (ts.Days < 1)
                e.CellStyle.BackColor = Color.Red;
            else if (ts.Days < 3)
                e.CellStyle.BackColor = Color.Yellow;
        }

        /// <summary>
        /// Hides the form when it should close.  Cancels the event if application is exiting
        /// </summary>
        private void OptionsForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Set or unset startup status in registry
            // SetStartup();

            this.Hide();
            e.Cancel = !exitingValue;
        }

        /// <summary>
        /// Update the registry to launch the application with Windows (or not)
        /// </summary>
        private static void SetStartup()
        {/*
            RegistryKey runKey = null;
            try
            {
                //System.Security.Permissions.RegistryPermission rp = new System.Security.Permissions.RegistryPermission(System.Security.Permissions.RegistryPermissionAccess.AllAccess, "Software\\Microsoft\\Windows\\CurrentVersion\\Run");
                //if( rp.IsUnrestricted )...

                runKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);

                if (Properties.Settings.Default.AutoStart)
                {
                    runKey.SetValue("HorizonClient", Application.ExecutablePath);
                }
                else
                {
                    runKey.DeleteValue("HorizonClient");
                }
            }
            catch
            {
                // Errors can be ignored since exception probably just means trying to delete
                // a key not present.
            }
            finally
            {
                if (runKey != null)
                    runKey.Close();
            }*/
        }

        /// <summary>
        /// Initializes and shows the LibraryForm to add a new library
        /// </summary>
        private void newLibraryButton_Click(object sender, EventArgs e)
        {
            libForm.CurrentLibrary = new Library();

            if (libForm.ShowDialog() == DialogResult.OK)
            {
                libForm.CurrentLibrary.Init();
                librariesValue.Add(libForm.CurrentLibrary);

                librariesListBox.DataSource = null;
                librariesListBox.DataSource = librariesValue;
                librariesListBox.DisplayMember = "Name";

                librariesListBox.SelectedItem = libForm.CurrentLibrary;
            }
        }

        /// <summary>
        /// Invoked when Edit button is clicked for libraries
        /// </summary>
        private void editLibraryButton_Click(object sender, EventArgs e)
        {
            EditLibrary();
        }

        /// <summary>
        /// Initializes and shows LibraryForm to edit the selected library
        /// </summary>
        private void EditLibrary()
        {
            if (selectedLibrary == null) return;

            libForm.CurrentLibrary = selectedLibrary;

            if (libForm.ShowDialog() == DialogResult.OK)
            {
                librariesListBox.DataSource = null;
                librariesListBox.DataSource = librariesValue;
                librariesListBox.DisplayMember = "Name";
            }
        }

        /// <summary>
        /// Removes the currently selected library
        /// </summary>
        private void deleteLibraryButton_Click(object sender, EventArgs e)
        {
            if (selectedLibrary != null)
            {
                librariesValue.Remove(selectedLibrary);
                librariesListBox.DataSource = null;
                librariesListBox.DataSource = librariesValue;
                librariesListBox.DisplayMember = "Name";
            }
        }

        /// <summary>
        /// Invoked if a library item is double-clicked
        /// </summary>
        private void librariesListBox_DoubleClick(object sender, EventArgs e)
        {
            EditLibrary();
        }

        /// <summary>
        /// Invoked if a patron is double-clicked
        /// </summary>
        private void patronsListBox_DoubleClick(object sender, EventArgs e)
        {
            EditPatron();
        }

        private void aboutButton_Click(object sender, EventArgs e)
        {
            string msg = string.Format("Check it Out!\r\nWritten by Arian T. Kulp\r\nOriginally published on MSDN Coding 4 Fun\r\nVersion = {0}\r\nPath = {1}\r\nSettings = {2}",
                Application.ProductVersion,
                Application.ExecutablePath,
                Application.LocalUserAppDataPath);

            MessageBox.Show(msg, "Check it Out!");
        }
   }
}